<?php
declare(strict_types=1);

namespace App\Service;

use App\Library\Api\InnerApi;
use App\Model\Entity\JnAdminUser;
use App\Model\Entity\JnSuppliersUsers;
use phpDocumentor\Reflection\Types\Boolean;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Db\DB;
use Swoft\Log\Helper\CLog;

/**
 * @Bean("UsersService")
 * Class UsersService
 * @package App\Service
 */
class UsersService {
    /**
     * @param $params
     * @param int $page
     * @param int $pageSize
     * @return array
     * @throws \Swoft\Db\Exception\DbException
     */
    public function getList(array $params , int $page, int $pageSize) : array
    {
        $select  = JnSuppliersUsers::select();
        if (isset($params ['username']) && $params ['username'] )
        {
            $select->where('username' ,$params ['username'] );
        }

        if (isset($params ['userTypes']) && $params ['userTypes'] )
        {
            $select->whereIn('user_type' ,$params ['userTypes'] );
        }

        if (isset($params ['userType']) && $params ['userType'] )
        {
            $select->where('user_type' ,$params ['userType'] );
        }

        if (isset($params ['mobile']) && $params ['mobile'] )
        {
            $select->where('mobile' ,$params ['mobile'] );
        }

        if (isset($params ['nickname']) && $params ['nickname'])
        {
            $select->where('nickname' ,$params ['nickname'] );
        }

        if (isset($params ['search']) && $params ['search'])
        {
            $select->whereRaw("(username like '%{$params ['search']}%' or nickname like '%{$params ['search']}%' or contract like '%{$params ['search']}%')") ;
        }

        if (isset($params ['status']) && $params ['status'] !== '')
        {
            $select->where('status' , $params ['status']);
        }

        if (isset($params ['contract']) && $params ['contract'])
        {
            $select->where('contract' , $params ['contract']);
        }
        $total = $select->count();
        $list = $select->forPage($page, $pageSize)->orderBy('id' , 'desc')
                ->get();
        return [
            'total' => $total,
            'list' => $list,
            ];
    }

    public function addUser($params) : int
    {
        $data = [
            'username'  => isset($params ['username']) ? $params ['username'] : '',
            'nickname'  => isset($params ['nickname']) ? $params ['nickname'] : '',
            'userType'  => isset($params ['userType']) ? intval($params ['userType']) : '',
            'mobile'    => isset($params ['mobile']) ? $params ['mobile'] : '',
            'email'     => isset($params ['email']) ? $params ['email'] : '',
            'contract'  => isset($params ['contract']) ? $params ['contract'] : '',
            'note'      => isset($params ['note']) ? $params ['note'] : '',
        ];

        $password = $this->generatePassword();
        $data ['password'] = password_hash($password , PASSWORD_DEFAULT);
        $data ['addTime'] = time();
        $data ['updateTime'] = time();

        //关联主账号
        $service_adminuser = new AdminUserService();
        $adminInfo = $service_adminuser->getInfoByWhere(['adminMobile' => $data['mobile']]);
        $adminUserId = $adminInfo ?$adminInfo ['userId']: 0;
        $data ['adminUserId'] = $adminUserId;

        $user = JnSuppliersUsers::new($data);
        $user->save();
        $userId = $user->getId();

        if (!$userId) return 0;

        //发送短信
//        $smsApi = new InnerApi();
//        $res = $smsApi->sendResetPassword($data ['mobile'] , $password);
        if (!$adminInfo)
        {
           $adminUserId = $service_adminuser->addUserSimple($data ['mobile'] , $userId);
           JnSuppliersUsers::find($userId)->update(['admin_user_id' =>$adminUserId ]);
        }

        //分配权限
        $service_adminuser->assignAuthority($adminUserId , $this->getUserRole($data ['userType']));

        return $userId;
    }

    /**
     * @param $userType
     * @return array|mixed
     *
     * TODO: 暂时写死，之后再想办法
     */
    private function getUserRole($userType) {
        $role_list = [
            '8' => ['portal_partner'],
            '9' => ['portal_big_deal_site'],
        ];

        return isset($role_list [$userType]) ? $role_list [$userType] : [];
    }


    /**
     * @param int $userId
     * @param array $params
     * @return bool
     */
    public function editUser(int $userId ,array $params) :bool
    {
        $res =  JnSuppliersUsers::where(['id'=>$userId])->update($params);
        return $res ? true : false;
    }

    public function changeStatus(int $userId , int $status) :bool
    {
        $res =  JnSuppliersUsers::where(['id'=>$userId])->update(['status'=>$status]);
        return $res ?true :false;
    }

    /**
     * @param $userId
     * @return array
     */
    public function resetPass(int $userId) : array
    {
        $ret = [
            'succ'  => false,
            'err'   => '',
        ];
        $userInfo = JnSuppliersUsers::find($userId);

        if (!$userInfo) {
            $ret ['err'] = '账号不存在';
            return $ret;
        }
        $password = $this->generatePassword();

        $smsApi = new InnerApi();
        $res = $smsApi->sendResetPassword($userInfo ['mobile'] , $password);

        if (!$res) {
            $ret ['err'] = '短信发送失败';
            return $ret;
        }

        $data = [
            'password' => password_hash($password, PASSWORD_DEFAULT),
            'update_time' => time(),
        ];
        $res = JnSuppliersUsers::find($userId)->update($data);

        if (!$res) {
            $ret ['err'] = '短信发送失败';
            return $ret;
        }

        $ret ['succ'] = true;
        return $ret;
    }

    private function generatePassword($length = 6) :string
    {
        // 密码字符集，可任意添加你需要的字符
        $chars = 'abcdefghkmnpqrstwxyzABCDEFGHKLMNPQRSTWXYZ23456789';
        $password = '';
        for ($i = 0; $i < $length; $i++) {
            // 这里提供两种字符获取方式
            // 第一种是使用 substr 截取$chars中的任意一位字符；
            // 第二种是取字符数组 $chars 的任意元素
            // $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
            $password .= $chars[ mt_rand(0, strlen($chars) - 1) ];
        }
        return $password;
    }


    public function verfify(string $username , string $password) :bool
    {
        $userInfo = JnSuppliersUsers::where('username' , $username)->first();

        if ($userInfo) {
            $userInfo = $userInfo->toArray();
            return (bool)password_verify($password , $userInfo ['password']);
        }
        return false;
    }

    public function modifyPass(string $username , string $password) :bool
    {
        return (bool)JnSuppliersUsers::where('username' , $username)->update(['password' => password_hash($password ,PASSWORD_DEFAULT)]);
    }
}